<?php
/**
 * lucene索引模型
 * @author       Steven.liao
 */
class Lucene implements iLucene
{
	/**
	 * 索引配置文件数据
	 * @var      object
	 */
	protected $_ini;

	/**
	 * 索引名称
	 * @var      string
	 */
	protected $_name;

	/**
	 * 返回数据条数
	 * @var      int
	 */
	protected $_limit = 50;

	/**
	 * 执行时间
	 * @var      int
	 */
	protected $_time;

	/**
	 * 当前页
	 * @var      int
	 */
	protected $_page = 1;

	/**
	 * 查询的关键字
	 */
	protected $_keyword;

	/**
	 * Document 列表
	 */
	protected $_docs = array();

	/**
	 * 是否启用缓存
	 */
	protected $_cache = true;

	protected $_url = "http://192.168.10.254:8080/Service/SE";
	/**
	 * 初始化
	 * 读到配置文件,
	 * 设定索引编码
	 * @return   void
	 */
	public function __construct()
	{
		$this->_logger = Logger::factory('Lucene','db');
	}
	/**
	 * 设定主机URL;
	 * @param string $url
	 * @return Object this
	 */
	public function setURL($url){
		$this->_url = $url;
		return $this;
	}
	/**
	 * 取得主机URL;
	 * @return String
	 */
	public function getURL(){
		return $this->_url;
	}
	/**
	 * 返回索引对象
	 * @param    string $name    索引名，对应index.ini文件
	 * @return   object
	 */
	public function setName($name)
	{
		$this->_name = $name;
		return $this;
	}

	/**
	 * 取得索引名
	 * @return   string
	 */
	public function getName()
	{
		return $this->_name;
	}

	/**
	 * 设定查询的关键字
	 * @param    string $keyword    当前查询的关键字
	 * @return   object
	 */
	public function setKeyword($string)
	{
		$this->_keyword = $string;
		return $this;
	}

	/**
	 * 取得当前要查询的关键字
	 * @return   string
	 */
	public function getKeyword()
	{
		return $this->_keyword;
	}

	/**
	 * 设置返回数据条数
	 * @param    int $limit    数据条数
	 * @return   object
	 */
	public function setLimit($limit)
	{
		$this->_limit = $limit;
		return $this;
	}

	/**
	 * 取得返回数据条数
	 * @return   int
	 */
	public function getLimit()
	{
		return $this->_limit;
	}

	/**
	 * 设定当前返回页数据
	 * @param    int $page    页码数
	 * @return   object
	 */
	public function setPage($page)
	{
		$this->_page = $page;
		return $this;
	}

	/**
	 * 取得当前页数
	 * @return   int
	 */
	public function getPage()
	{
		return $this->_page;
	}

	/**
	 * 查询索引 对外
	 * @return   array
	 */
	public function query($keyword=null,$page=null,$limit=null){
		if($page != null) $this->setPage($page);
		if($limit != null) $this->setLimit($limit);
		$this->setKeyword($keyword);
		$xml = '<query name="'.$this->_name.'" page="'.$this->_page.'" limit="'.$this->_limit.'">';
		$xml .= '<keyword>'.$this->xmlencode($this->_keyword).'</keyword>';
		$xml .= '</query>';
		return $this->post($xml);
		//Zend_Debug::dump($data);
	}

	/**
	 * 提交数据 POST XML
	 * @param String $xml;
	 * @return Object response;
	 */
	private function post($xml){
		$this->_xml = $xml;
		$client = new Zend_Http_Client($this->_url);
		$client->setMethod(Zend_Http_Client::POST);
		$client->setRawData($xml);
		$response = $client->request();
		try{
			$d = Zend_Json::decode(Zend_Json::fromXml($response->getBody()));
			$data = $d['body'];
		}catch (Exception $e){
			$data['error'] = $e->getMessage();
			echo $response->getBody();
		}
		return $data;
		//echo $response->getBody();
	}

	/**
	 * 过滤XML的代码 
	 *
	 * @param string $val
	 * @return string
	 */
	private function xmlencode($val){
		$val = str_replace("&","&amp;",$val);
		$val = str_replace("<","&lt;",$val);
		$val = str_replace(">","&gt;",$val);
		$val = str_replace("'","&apos;",$val);
		$val = str_replace("\"",'&quot;',$val);
		return $val;
	}

	/**
	 * 加入索引数据 单条
	 * @param    array $data    字段数组
	 * @return   boolean
	 */
	public function add(Array $data)
	{
		$xml ='<create name="'.$this->_name.'">';
		$xml.='<doc>';
		foreach ($data as $field=>$val){
			$xml.='<'.$field.'>'.$this->xmlencode($val).'</'.$field.'>';
		}
		$xml.='</doc>';
		$xml .= '</create>';
		return $this->post($xml);
	}
	/**
	 * 加入索引数据 多条
	 * @param    array $data    字段数组
	 * @return   boolean
	 */
	public function adds($datas){
		$xml ='<create name="'.$this->_name.'">';
		foreach($datas as $data){
			$xml.='<doc>';
			foreach ($data as $field=>$val){
				$xml.='<'.$field.'>'.$this->xmlencode($val).'</'.$field.'>';
			}
			$xml.='</doc>';
		}
		$xml .= '</create>';
		return $this->post($xml);
	}
	/**
	 * 优化当前索引
	 * @return   array
	 */
	public function optimize()
	{
		$xml ='<optimize name="'.$this->_name.'" />';
		return $this->post($xml);
	}

	/**
	 * 索引commit
	 * @return   array
	 */
	public function commit()
	{
		$xml ='<commit name="'.$this->_name.'" />';
		return $this->post($xml);
	}

	/**
	 * 删除索引数据
	 * @param int or array $id    当前索引ID 
	 * @return   int
	 */
	public function delete($id)
	{
		$xml ='<delete name="'.$this->_name.'">';
		if(is_array($id)){
			foreach ($id as $val){
				$xml .='<doc id="'.$val.'"/>';
			}
		}else{
			$xml .='<doc id="'.$id.'"/>';
		}
		$xml .= '</delete>';
		return $this->post($xml);
	}

	/**
	 * 更新索引数据
	 * @param    int $id    当前索引ID
	 * @param    int $data    当前数据数组
	 * @return   int
	 */
	public function update($data)
	{
		$xml ='<update name="'.$this->_name.'">';
		$xml .='<doc id="'.$data['id'].'">';
		unset($data['id']);
		foreach($data as $field=>$val){
			$xml.='<'.$field.'>'.$this->xmlencode($val).'</'.$field.'>';
		}
		$xml .='</doc>';
		$xml .= '</update>';
		return $this->post($xml);
	}

	public function updates($datas){
		$xml ='<update name="'.$this->_name.'">';
		foreach ($datas as $data){
			$xml .='<doc id="'.$data['id'].'">';
			unset($data['id']);
			foreach($data as $field=>$val){
				$xml.='<'.$field.'>'.$this->xmlencode($val).'</'.$field.'>';
			}
			$xml .='</doc>';
		}
		$xml .= '</update>';
		//echo $xml;
		return $this->post($xml);
	}

	/**
	 * 统计索引数据
	 */
	public function count()
	{
		$xml ='<count name="'.$this->_name.'" />';
		return $this->post($xml);
	}

	public function getXML(){
		return $this->_xml;
	}
}